#include "sutility.h"

#include <algorithm>
#include <iterator>
#include <sstream>

namespace sds {

  template <typename Value, typename Container>
  std::string SVectorToString(const Container& container) {
    std::ostringstream os;
    std::copy(container.begin(), container.end(), 
	      std::ostream_iterator<Value>(os, " "));
    return os.str();
  }

  template <typename Container>
  std::string SVectorToString(const Container& container) {
    return SVectorToString<typename Container::value_type>(container);
  }

  std::string SAttributeToString(const SAttribute& attribute) {
    switch (attribute.getDataType()) {
    case CHAR:
    case UCHAR:
      {
	std::string value = attribute.getData<char, std::string>();
	int cut = value.find('\0');
	if (cut != -1) value.resize(cut);
	return value;
      }
    case INT8:
      return SVectorToString<int>(attribute.getData<signed char>());    
    case UINT8:
      return SVectorToString<int>(attribute.getData<unsigned char>());    
    case INT16:
      return SVectorToString(attribute.getData<signed short>());    
    case UINT16:
      return SVectorToString(attribute.getData<unsigned short>());    
    case INT32:
      return SVectorToString(attribute.getData<signed long>());    
    case UINT32:
      return SVectorToString(attribute.getData<unsigned long>());    
    case INT64:
      return SVectorToString(attribute.getData<signed long long>());    
    case UINT64:
      return SVectorToString(attribute.getData<unsigned long long>());    
    case FLOAT32:
      return SVectorToString(attribute.getData<float>());    
    case FLOAT64:
      return SVectorToString(attribute.getData<double>());    
    default:
      break;
    }
    return std::string();
  }

  std::string SDataTypeToString(const SDataType& dataType) {
    switch (dataType) {
    case CHAR:
      return "CHAR";
    case UCHAR:
      return "UCHAR";
    case INT8:
      return "INT8";
    case UINT8:
      return "UINT8";
    case INT16:
      return "INT16";
    case UINT16:
      return "UINT16";
    case INT32:
      return "INT32";
    case UINT32:
      return "UINT32";
    case INT64:
      return "INT64";
    case UINT64:
      return "UINT64";
    case FLOAT32:
      return "FLOAT32";
    case FLOAT64:
      return "FLOAT64";
    default:
      return "UNDEFINED";  
    }
  }
}
